package com.ruoyi.business.service.impl;

import com.ruoyi.business.domain.EquipmentVariables;
import com.ruoyi.business.domain.EquipmentVariablesHistory;
import com.ruoyi.business.mapper.EquipmentVariablesHistoryMapper;
import com.ruoyi.business.mapper.EquipmentVariablesMapper;
import com.ruoyi.business.service.IEquipmentVariablesHistoryService;
import com.ruoyi.business.vo.EquipmentVariablesHistoryVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 设备变量历史数据Service业务层处理
 *
 * @author ldkj
 * @date 2025-02-27
 */
@Service
public class EquipmentVariablesHistoryServiceImpl implements IEquipmentVariablesHistoryService
{
    @Autowired
    private EquipmentVariablesHistoryMapper equipmentVariablesHistoryMapper;

    @Autowired
    private EquipmentVariablesMapper equipmentVariablesMapper;

    /**
     * 查询设备变量历史数据
     *
     * @param historyId 设备变量历史数据主键
     * @return 设备变量历史数据
     */
    @Override
    public EquipmentVariablesHistory selectEquipmentVariablesHistoryByHistoryId(Long historyId)
    {
        return equipmentVariablesHistoryMapper.selectEquipmentVariablesHistoryByHistoryId(historyId);
    }

    /**
     * 查询设备变量历史数据列表
     *
     * @param equipmentVariablesHistory 设备变量历史数据
     * @return 设备变量历史数据
     */
    @Override
    public List<EquipmentVariablesHistory> selectEquipmentVariablesHistoryList(EquipmentVariablesHistory equipmentVariablesHistory)
    {
        return equipmentVariablesHistoryMapper.selectEquipmentVariablesHistoryList(equipmentVariablesHistory);
    }

    /**
     * 根据变量ID查询历史数据列表
     *
     * @param variableId 变量ID
     * @return 设备变量历史数据集合
     */
    @Override
    public List<EquipmentVariablesHistory> selectEquipmentVariablesHistoryByVariableId(Long variableId)
    {
        return equipmentVariablesHistoryMapper.selectEquipmentVariablesHistoryByVariableId(variableId);
    }

    /**
     * 根据变量名称查询历史数据列表
     *
     * @param variableName 变量名称
     * @return 设备变量历史数据集合
     */
    @Override
    public List<EquipmentVariablesHistory> selectEquipmentVariablesHistoryByVariableName(String variableName)
    {
        return equipmentVariablesHistoryMapper.selectEquipmentVariablesHistoryByVariableName(variableName);
    }



    /**
     * 根据操作类型查询历史数据列表
     *
     * @param operationType 操作类型
     * @return 设备变量历史数据集合
     */
    @Override
    public List<EquipmentVariablesHistory> selectEquipmentVariablesHistoryByOperationType(String operationType)
    {
        return equipmentVariablesHistoryMapper.selectEquipmentVariablesHistoryByOperationType(operationType);
    }

    /**
     * 新增设备变量历史数据
     *
     * @param equipmentVariablesHistory 设备变量历史数据
     * @return 结果
     */
    @Override
    public int insertEquipmentVariablesHistory(EquipmentVariablesHistory equipmentVariablesHistory)
    {
        if (equipmentVariablesHistory.getRecordTimestamp() == null) {
            equipmentVariablesHistory.setRecordTimestamp(new Date());
        }
        return equipmentVariablesHistoryMapper.insertEquipmentVariablesHistory(equipmentVariablesHistory);
    }

    /**
     * 修改设备变量历史数据
     *
     * @param equipmentVariablesHistory 设备变量历史数据
     * @return 结果
     */
    @Override
    public int updateEquipmentVariablesHistory(EquipmentVariablesHistory equipmentVariablesHistory)
    {
        return equipmentVariablesHistoryMapper.updateEquipmentVariablesHistory(equipmentVariablesHistory);
    }

    /**
     * 批量删除设备变量历史数据
     *
     * @param historyIds 需要删除的设备变量历史数据主键
     * @return 结果
     */
    @Override
    public int deleteEquipmentVariablesHistoryByHistoryIds(Long[] historyIds)
    {
        return equipmentVariablesHistoryMapper.deleteEquipmentVariablesHistoryByHistoryIds(historyIds);
    }

    /**
     * 删除设备变量历史数据信息
     *
     * @param historyId 设备变量历史数据主键
     * @return 结果
     */
    @Override
    public int deleteEquipmentVariablesHistoryByHistoryId(Long historyId)
    {
        return equipmentVariablesHistoryMapper.deleteEquipmentVariablesHistoryByHistoryId(historyId);
    }

    /**
     * 根据变量ID删除历史数据
     *
     * @param variableId 变量ID
     * @return 结果
     */
    @Override
    public int deleteEquipmentVariablesHistoryByVariableId(Long variableId)
    {
        return equipmentVariablesHistoryMapper.deleteEquipmentVariablesHistoryByVariableId(variableId);
    }

    /**
     * 清理指定天数之前的历史数据
     *
     * @param days 保留天数
     * @return 结果
     */
    @Override
    public int cleanHistoryDataBeforeDays(int days)
    {
        return equipmentVariablesHistoryMapper.cleanHistoryDataBeforeDays(days);
    }

    /**
     * 手动记录设备变量历史数据
     *
     * @param variableId 变量ID
     * @param operationType 操作类型
     * @param oldValue 旧值
     * @param newValue 新值
     * @return 结果
     */
    @Override
    public int recordVariableHistory(Long variableId, String operationType, String oldValue, String newValue)
    {
        // 查询当前变量信息
        EquipmentVariables currentVariable = equipmentVariablesMapper.selectEquipmentVariablesByVariableId(variableId);
        if (currentVariable == null) {
            return 0;
        }

        // 创建历史记录
        EquipmentVariablesHistory history = new EquipmentVariablesHistory();
        history.setVariableId(variableId);
        history.setVariableName(currentVariable.getVariableName());
        history.setVariableEnName(currentVariable.getVariableEnName());
        history.setVariableValue(currentVariable.getVariableValue());
        history.setRecordTimestamp(new Date());
        history.setOperationType(operationType);
        history.setOldValue(oldValue);
        history.setNewValue(newValue);

        return equipmentVariablesHistoryMapper.insertEquipmentVariablesHistory(history);
    }

    /**
     * 批量新增设备变量历史数据
     *
     * @param historyList 设备变量历史数据集合
     * @return 结果
     */
    @Override
    public int batchInsertEquipmentVariablesHistory(List<EquipmentVariablesHistory> historyList)
    {
        if (historyList == null || historyList.isEmpty()) {
            return 0;
        }

        // 设置默认时间戳
        Date currentTime = new Date();
        for (EquipmentVariablesHistory history : historyList) {
            if (history.getRecordTimestamp() == null) {
                history.setRecordTimestamp(currentTime);
            }
        }

        return equipmentVariablesHistoryMapper.batchInsertEquipmentVariablesHistory(historyList);
    }

    /**
     * 根据时间范围获取指定变量的历史记录对象列表
     * @param startTime
     * @param endTime
     * @param variableEnNames
     * @return
     */
    @Override
    public List<EquipmentVariablesHistoryVO> getVariablesHistoryByTimeRange(Date startTime, Date endTime, List<String> variableEnNames) {
        List<EquipmentVariablesHistory> list = equipmentVariablesHistoryMapper
                .selectByTimeRangeAndVariables(startTime, endTime, variableEnNames);

        // 按 variableEnName 分组封装 VO
        Map<String, List<EquipmentVariablesHistory>> grouped = list.stream()
                .collect(Collectors.groupingBy(EquipmentVariablesHistory::getVariableEnName));

        // 定义需要计算平均值的温度变量集合
        List<String> tempVariables = Arrays.asList(
                "mildMildfurntemp",
                "mildMildfurntemp1",
                "mildMildfurntemp2",
                "mildMildfurntemp3"
        );
        //全部数据定义
        List<EquipmentVariablesHistoryVO> collected = grouped.entrySet().stream()
            .filter(entry -> !tempVariables.contains(entry.getKey())) // 过滤掉四个温度变量
            .map(entry -> {
            String enName = entry.getKey();
            List<EquipmentVariablesHistory> records = entry.getValue();

            // 抽稀处理，最多50个点
            List<EquipmentVariablesHistory> sampledRecords = sampleRecords(records, 50);

            EquipmentVariablesHistoryVO vo = new EquipmentVariablesHistoryVO();
            vo.setVariableEnName(enName);
            vo.setVariableName(records.get(0).getVariableName());
            vo.setRecords(sampledRecords);
            return vo;
        }).collect(Collectors.toList());

        // 检查是否需要计算温度平均值（请求参数中包含任意一个温度变量时）
        boolean needCalculateAvg = tempVariables.stream().anyMatch(variableEnNames::contains);
        if (needCalculateAvg) {
            // 收集所有时间点，确保完整覆盖所有温度变量的记录时间
            Set<Date> allTimes = new TreeSet<>();
            tempVariables.forEach(var -> {
                List<EquipmentVariablesHistory> records = grouped.getOrDefault(var, Collections.emptyList());
                records.forEach(record -> allTimes.add(record.getRecordTimestamp()));
            });

            // 计算每个时间点的平均值
            List<EquipmentVariablesHistory> avgRecords = new ArrayList<>();
            for (Date time : allTimes) {
                double sum = 0.0;
                // 遍历四个温度变量，获取对应时间点的值，无值或负数均为0
                for (String var : tempVariables) {
                    List<EquipmentVariablesHistory> varRecords = grouped.getOrDefault(var, Collections.emptyList());
                    // 查找当前时间点的记录
                    EquipmentVariablesHistory targetRecord = varRecords.stream()
                            .filter(record -> time.equals(record.getRecordTimestamp()))
                            .findFirst()
                            .orElse(null);

                    // 解析值，无记录、解析失败或值为负数均处理为0
                    double value = 0.0;
                    if (targetRecord != null && targetRecord.getVariableValue() != null) {
                        try {
                            double parsedValue = Double.parseDouble(targetRecord.getVariableValue());
                            // 如果解析后的值为负数，也设置为0
                            value = parsedValue < 0 ? 0.0 : parsedValue;
                        } catch (NumberFormatException e) {
                            // 数值格式错误时默认0
                            value = 0.0;
                        }
                    }
                    sum += value;
                }

                // 计算平均值（4个变量）
                double avg = sum / tempVariables.size();
                // 确保平均值不会为负数（虽然四个非负值的平均不可能为负，这里做双重保障）
                avg = Math.max(0.0, avg);

                // 创建平均值记录
                EquipmentVariablesHistory avgRecord = new EquipmentVariablesHistory();
                avgRecord.setRecordTimestamp(time);
                avgRecord.setVariableEnName("averageValue");
                avgRecord.setVariableName("炉膛温度");
                avgRecord.setVariableValue(String.format("%.2f", avg));
                SimpleDateFormat format = new SimpleDateFormat("HH:mm");
                avgRecord.setRTimestamp(format.format(time));
                avgRecords.add(avgRecord);
            }

            // 对平均值记录进行抽稀处理
            List<EquipmentVariablesHistory> sampledAvgRecords = sampleRecords(avgRecords, 50);

            // 创建平均值VO并添加到结果集
            EquipmentVariablesHistoryVO avgVo = new EquipmentVariablesHistoryVO();
            avgVo.setVariableEnName("averageValue");
            avgVo.setVariableName("炉膛温度");
            avgVo.setRecords(sampledAvgRecords);
            collected.add(avgVo);
        }

        return collected;
    }

    /**
     * 数据抽稀
     * @param list 原始数据列表
     * @param maxPoints 最大点位数
     * @return 抽稀后的列表
     */
    private List<EquipmentVariablesHistory> sampleRecords(List<EquipmentVariablesHistory> list, int maxPoints) {
        int size = list.size();
        if (size <= maxPoints) {
            return list; // 不需要抽稀
        }

        List<EquipmentVariablesHistory> result = new ArrayList<>();
        result.add(list.get(0)); // 保留第一个

        int step = (size - 1) / (maxPoints - 1); // 间隔索引
        for (int i = 1; i < maxPoints - 1; i++) {
            int idx = i * step;
            if (idx >= size - 1) idx = size - 2; // 防止越界
            result.add(list.get(idx));
        }

        result.add(list.get(size - 1)); // 保留最后一个
        return result;
    }
}
